home *** CD-ROM | disk | FTP | other *** search
- % File : READ.PL
- % Author : D.H.D.Warren + Richard O'Keefe
- % Modified for SB-Prolog by Saumya K. Debray & Deeporn Beardsley
- % Updated: July 1988
- % Purpose: Read Prolog terms in Dec-10 syntax.
- /*
- Modified by Alan Mycroft to regularise the functor modes.
- This is both easier to understand (there are no more '?'s),
- and also fixes bugs concerning the curious interaction of cut with
- the state of parameter instantiation.
-
- Since this file doesn't provide "metaread", it is considerably
- simplified. The token list format has been changed somewhat, see
- the comments in the RDTOK file.
-
- I have added the rule X(...) -> apply(X,[...]) for Alan Mycroft.
- */
-
- /****************************************************************************
- * *
- * This file has been changed by to include Modules Extensions *
- * Changes by : Brian Paxton 1991/92 *
- * Last update : June 1992 *
- * *
- * Organisation : University of Edinburgh. *
- * For : Departments of Computer Science and Artificial Intelligence *
- * Fourth Year Project. *
- * *
- ****************************************************************************/
-
- $read_export([$read/1,$read/2,$read_module/1,$read/3]).
-
- % $read_use : $bmeta, $meta, $bio, $io, $blist, $retr, $name, $modules
-
- % $read(?Answer).
-
- $read(Answer) :- $read(Answer, _, perv).
-
- % $read(?Answer, ?Arg)
- % reads a term from the current input stream. Arg may be the list of
- % variables in the expression (a list of [Atom=Variable] pairs) or a
- % structure tag.
-
- $read(Answer, Variables) :-
- var(Variables), !,
- $read(Answer, Variables, perv).
-
- $read(Answer, Tag) :-
- $isa_structuretag(Tag),
- $read(Answer, _, Tag).
-
- % $read(?Answer, -Vars, ?Str)
- % Read Answer from the standard input with respect to the structure Str,
- % giving a list of variables Vars.
-
- $read(Answer,Variables,Tag) :-
- ( $isa_structuretag(Tag) ->
- ( repeat,
- $read_tokens(Tokens, Variables),
- ( Tag == perv -> Tokens1 = Tokens ;
- $dereference_input(Tokens, Tokens1, Tag) ),
- ( ( $read(Tokens1, 1200, Term, Leftover, Tag),
- $read_all(Leftover) ;
- $read_syntax_error(Tokens1) ) ),
- !,
- Term = Answer ) ;
- ( $writename('*** Error : Third argument to read/3 must be a structure tag'),
- $nl, fail ) ).
-
- % $dereference_input(+Tokens, -New, +Tag)
- %
- % Once the tokens have been read in, this routine is called to pre-process
- % any colons (:) in the input into the correct dereferenced item. All
- % paths must be written in the infix : notation. After processing, the result
- % is a list of tokens like the original list, but any paths have been
- % changed into an atom with the correct structure tag which can be passed
- % on to the original read processing routines.
-
- $dereference_input([], [], _).
- $dereference_input([atom(Atom), atom(':')|Tail],[atom(Newatom)|Newtail],Tag) :-
- $get_path([atom(Atom), atom(':')|Tail], Path, Function, Leftover), !,
- $dereference_path(Path, Function, Newatom, Tag),
- $dereference_input(Leftover, Newtail, Tag).
- $dereference_input([atom(':')|_], _, _) :- !,
- $writename('** Error : Illegal use of : path constructor'),
- $nl, fail.
- $dereference_input([Head|Tail], [Head|Newtail], Tag) :- !,
- $dereference_input(Tail, Newtail, Tag).
-
- $get_path([atom(Atom1), atom(':'), atom(Atom2), atom(':')|Tail],
- Atom1:Path, Function, Leftover) :-
- $get_path([atom(Atom2), atom(':')|Tail], Path, Function, Leftover).
- $get_path([atom(Atom1), atom(':'), atom(Atom2)|Tail], Atom1, Atom2, Tail).
-
- $dereference_path(Path, Item, Newitem, Strtag) :-
- $module_structure(_,Strtag,Substrs,_,_),
- $memberchk(Path ---> Tag, Substrs) ->
- $dismantle_name(Newitem, Item, Tag) ;
- ( $writename('*** Error: Unknown structure '),
- $write(Path),
- $writename(' during read'),
- $nl, fail ).
-
-
- % $read_all(+Tokens)
- %
- $read_all([]) :- !.
- $read_all(S) :-
- $read_syntax_error(['operator expected after expression'], S).
-
-
- % $read_expect(Token, TokensIn, TokensOut)
- % reads the next token, checking that it is the one expected, and
- % giving an error message if it is not. It is used to look for
- % right brackets of various sorts, as they're all we can be sure of.
-
- $read_expect(Token, [Token|Rest], Rest) :- !.
- $read_expect(Token, S0, _) :-
- $read_syntax_error([Token,'or operator expected'], S0).
-
-
- % I want to experiment with having the operator information held as
- % ordinary Prolog facts. For the moment the following predicates
- % remain as interfaces to curr_op.
- % $read_prefixop(O -> Self, Rarg)
- % $read_postfixop(O -> Larg, Self)
- % $read_infixop(O -> Larg, Self, Rarg)
-
- % Note that to perform this next predicate in the modules environment, we
- % need to pass in the current structure tag and return the name of the
- % operator (which is not necessarily the one passed in - it may now
- % have a tag).
-
-
- $check_mapped(F1,Arity,F2,Tag) :-
- $symtype($mapped_function(_,_,_,_), Type),
- ( ( Type > 0, $mapped_function(F1,Arity,F2,_) ) ; % &&
- F2 = F1 ),!.
-
- % Purpose of line ** and similar ones :
- % If the operator under consideration has not yet been tagged it is either,
- % a pervasive operator of the desired type or a operator from the current
- % structure of the required type (or neither). This code first tries the
- % current structure operator, then the pervasive one.
-
- $read_prefixop(F0, F2, X, Y, Tag) :-
- ( ( $dismantle_name(F0, _, perv), $dismantle_name(F1, F0, Tag) ) ; %**
- F1 = F0 ),
- $read_prefixop(F1, X, Y),
- $check_mapped(F1,1,F2,Tag), !.
-
- $read_prefixop(Op, Prec, Prec) :-
- $read_curr_op(Prec, fy, Op), !.
- $read_prefixop(Op, Prec, Less) :-
- $read_curr_op(Prec, fx, Op), !,
- Less is Prec-1.
-
- $read_postfixop(F0, F2, Prec, Prec1, Tag) :-
- ( ( $dismantle_name(F0, _, perv), $dismantle_name(F1, F0, Tag) ) ;
- F1 = F0 ),
- $read_postfixop(F1, Prec, Prec1),
- $check_mapped(F1,1,F2,Tag), !.
-
- $read_postfixop(Op, Prec, Prec) :-
- $read_curr_op(Prec, yf, Op), !.
- $read_postfixop(Op, Less, Prec) :-
- $read_curr_op(Prec, xf, Op), !, Less is Prec-1.
-
- $read_infixop(F0, F2, X, Y, Z, Tag) :-
- ( ( $dismantle_name(F0, _, perv), $dismantle_name(F1, F0, Tag) ) ;
- F1 = F0 ),
- $read_infixop(F1, X, Y, Z),
- $check_mapped(F1,2,F2,Tag), !.
-
- $read_infixop(Op, Less, Prec, Less) :-
- $read_curr_op(Prec, xfx, Op), !, Less is Prec-1.
- $read_infixop(Op, Less, Prec, Prec) :-
- $read_curr_op(Prec, xfy, Op), !, Less is Prec-1.
- $read_infixop(Op, Prec, Prec, Less) :-
- $read_curr_op(Prec, yfx, Op), !, Less is Prec-1.
-
-
- $read_ambigop(F, F1, F2, L1, O1, R1, L2, O2, Tag) :-
- $read_postfixop(F, F1, L2, O2, Tag),
- $read_infixop(F, F2, L1, O1, R1, Tag), !.
-
-
- % $read(+TokenList, +Precedence, -Term, -LeftOver, +Tag)
- % parses a Token List in a context of given Precedence,
- % returning a Term and the unread Left Over tokens.
-
- :- mode($read,5,[nv,nv,d,d,d]).
-
-
- $read([Token|RestTokens], Precedence, Term, LeftOver, Tag) :-
- $read(Token, RestTokens, Precedence, Term, LeftOver, Tag).
- $read([], _, _, _, _) :-
- $read_syntax_error(['expression expected'], []).
-
-
- % $read(+Token, +RestTokens, +Precedence, -Term, -LeftOver, +Tag)
- % Renamed as well.
-
- :- mode($read,6,[nv,nv,c,d,d,d]).
-
- $read(var(Variable,_), ['('|S1], Precedence, Answer, S, Tag) :- !,
- $read(S1, 999, Arg1, S2, Tag),
- $read_args(S2, RestArgs, S3, Tag), !,
- $read_exprtl0(S3,apply(Variable,[Arg1|RestArgs]),Precedence,Answer,S,
- Tag).
-
- $read(var(Variable,_), S0, Precedence, Answer, S, Tag) :- !,
- $read_exprtl0(S0, Variable, Precedence, Answer, S, Tag).
-
- $read(atom(-), [number(Num)|S1], Precedence, Answer, S, Tag) :-
- Negative is -Num, !,
- $read_exprtl0(S1, Negative, Precedence, Answer, S, Tag).
-
- $read(atom(Functor), ['('|S1], Precedence, Answer, S, Tag) :- !,
- $read(S1, 999, Arg1, S2, Tag),
- $read_args(S2, RestArgs, S3, Tag),
- $length([Arg1|RestArgs],Arity),
- ( $pervasive(Functor/Arity) ->
- Functor0 = Functor ;
- ( $dismantle_name(Functor, _, Oldtag),
- ( Oldtag == perv -> $dismantle_name(Functor0, Functor, Tag) ;
- Functor0 = Functor ) ) ),
- $check_mapped(Functor0,Arity,Functor1,Tag),
- $univ(Term,[Functor1,Arg1|RestArgs]), !,
- $read_exprtl0(S3, Term, Precedence, Answer, S, Tag).
-
- $read(atom(Functor), S0, Precedence, Answer, S, Tag) :-
- $read_prefixop(Functor, Functor1, Prec, Right, Tag), !,
- $read_aft_pref_op(Functor1, Functor, Prec, Right, S0, Precedence,
- Answer, S, Tag).
-
- $read(atom(Atom), S0, Precedence, Answer, S, Tag) :- !,
- ( $pervasive0(Atom) ->
- Atom0 = Atom ;
- ( $dismantle_name(Atom, _, Oldtag),
- ( Oldtag == perv -> $dismantle_name(Atom0, Atom, Tag) ;
- Atom0 = Atom ) ) ),
- $check_mapped(Atom0,0,Atom1,Tag),
- $read_exprtl0(S0, Atom1, Precedence, Answer, S, Tag).
-
- $read(number(Num), S0, Precedence, Answer, S, Tag) :- !,
- $read_exprtl0(S0, Num, Precedence, Answer, S, Tag).
-
- $read('[', [']'|S1], Precedence, Answer, S, Tag) :- !,
- $read_exprtl0(S1, [], Precedence, Answer, S, Tag).
-
- $read('[', S1, Precedence, Answer, S, Tag) :- !,
- $read(S1, 999, Arg1, S2, Tag),
- $read_list(S2, RestArgs, S3, Tag), !,
- $read_exprtl0(S3, [Arg1|RestArgs], Precedence, Answer, S, Tag).
-
- $read('(', S1, Precedence, Answer, S, Tag) :- !,
- $read(S1, 1200, Term, S2, Tag),
- $read_expect(')', S2, S3), !,
- $read_exprtl0(S3, Term, Precedence, Answer, S, Tag).
-
- $read(' (', S1, Precedence, Answer, S, Tag) :- !,
- $read(S1, 1200, Term, S2, Tag),
- $read_expect(')', S2, S3), !,
- $read_exprtl0(S3, Term, Precedence, Answer, S, Tag).
-
- $read('{', ['}'|S1], Precedence, Answer, S, Tag) :- !,
- $read_exprtl0(S1, '{}', Precedence, Answer, S, Tag).
-
- $read('{', S1, Precedence, Answer, S, Tag) :- !,
- $read(S1, 1200, Term, S2, Tag),
- $read_expect('}', S2, S3), !,
- $read_exprtl0(S3, '{}'(Term), Precedence, Answer, S, Tag).
-
- $read(string(List), S0, Precedence, Answer, S, Tag) :- !,
- $read_exprtl0(S0, List, Precedence, Answer, S, Tag).
-
- $read(Token, S0, _, _, _, _) :-
- $read_syntax_error([Token,'cannot start an expression'], S0).
-
-
- % $read_args(+Tokens, -TermList, -LeftOver, +Tag)
- % parses {',' expr(999)} ')' and returns a list of terms.
-
- $read_args([Tok|S1], Term, S, Tag) :-
- '_$savecp'(CP),
- $read_args1(Tok,Term,S,S1,CP, Tag), '_$cutto'(CP).
- $read_args(S, _, _, _) :-
- $read_syntax_error([', or ) expected in arguments'], S).
-
- :- mode($read_args1,6,[c,nv,d,d,d,d]).
-
- $read_args1(',',[Term|Rest],S,S1,CP, Tag) :-
- $read(S1, 999, Term, S2, Tag), '_$cutto'(CP),
- $read_args(S2, Rest, S, Tag).
- $read_args1(')',[],S,S,_,_).
-
-
-
- % $read_list(+Tokens, -TermList, -LeftOver, +Tag)
- % parses {',' expr(999)} ['|' expr(999)] ']' and returns a list of terms.
-
- $read_list([Tok|S1],Term,S, Tag) :-
- '_$savecp'(CP),
- $read_list1(Tok,Term,S,S1,CP, Tag),
- '_$cutto'(CP).
- $read_list(S, _, _, _) :-
- $read_syntax_error([', | or ] expected in list'], S).
-
-
- :- mode($read_list1,6,[c,nv,d,d,d,d]).
-
- $read_list1(',',[Term|Rest],S,S1,CP, Tag) :-
- $read(S1, 999, Term, S2, Tag), '_$cutto'(CP),
- $read_list(S2, Rest, S, Tag).
- $read_list1('|',Rest,S,S1,CP, Tag) :-
- $read(S1, 999, Rest, S2, Tag), '_$cutto'(CP),
- $read_expect(']', S2, S).
- $read_list1(']',[],S,S,_,_).
-
-
- % $read_aft_pref_op(+Op, +Oldop, +Prec, +ArgPrec, +Rest, +Precedence, -Ans,
- % -LeftOver, +Tag)
- %
- % Since an operators internal name can be different from its typed name in
- % modular Prolog (because of a mapped function), we pass the typed name in
- % here just is case it turns out not to be an operator after all.
-
- :- mode($read_aft_pref_op,9,[nv,nv,nv,nv,nv,nv,d,d,d]).
-
- $read_aft_pref_op(Op, _, Oprec, Aprec, S0, Precedence, _, _, _) :-
- Precedence < Oprec, !,
- $read_syntax_error(['prefix operator',Op,'in context with precedence '
- ,Precedence], S0).
-
- $read_aft_pref_op(Op, Oldop, Oprec, Aprec, S0, Precedence, Answer, S, Tag) :-
- $read_peepop(S0, S1, Tag),
- $read_prefix_is_atom(S1, Oprec), % can't cut but would like to
- ( $pervasive0(Oldop) ->
- Oldop0 = Oldop ;
- ( $dismantle_name(Oldop, _, Oldtag),
- ( Oldtag == perv -> $dismantle_name(Oldop0, Oldop, Tag) ;
- Oldop0 = Oldop ) ) ),
- $check_mapped(Oldop0,0,Oldop1,Tag),
- $read_exprtl(S1, Oprec, Oldop1, Precedence, Answer, S, Tag).
-
- $read_aft_pref_op(Op, _, Oprec, Aprec, S1, Precedence, Answer, S, Tag) :-
- $read(S1, Aprec, Arg, S2, Tag),
- $univ(Term,[Op,Arg]), !,
- $read_exprtl(S2, Oprec, Term, Precedence, Answer, S, Tag).
-
-
- % The next clause fixes a bug concerning "mop dop(1,2)" where
- % mop is monadic and dop dyadic with higher Prolog priority.
-
- $read_peepop([atom(F),'('|S1], [atom(F),'('|S1], Tag) :- !.
- $read_peepop([atom(F)|S1], [infixop(F0,L,P,R)|S1], Tag) :-
- $read_infixop(F, F0, L, P, R, Tag).
- $read_peepop([atom(F)|S1], [postfixop(F0,L,P)|S1], Tag) :-
- $read_postfixop(F, F0, L, P, Tag).
- $read_peepop(S0, S0, _).
-
-
- % $read_prefix_is_atom(+TokenList, +Precedence)
- % is true when the right context TokenList of a prefix operator
- % of result precedence Precedence forces it to be treated as an
- % atom, e.g. (- = X), p(-), [+], and so on.
-
- $read_prefix_is_atom([Token|_], Precedence) :-
- $read_prefix_is_atom(Token, Precedence).
-
- $read_prefix_is_atom(infixop(_,L,_,_), P) :- L >= P.
- $read_prefix_is_atom(postfixop(_,L,_), P) :- L >= P.
- $read_prefix_is_atom(')', _).
- $read_prefix_is_atom(']', _).
- $read_prefix_is_atom('}', _).
- $read_prefix_is_atom('|', P) :- 1100 >= P.
- $read_prefix_is_atom(',', P) :- 1000 >= P.
- $read_prefix_is_atom([], _).
-
-
- % $read_exprtl0(+Tokens, +Term, +Prec, -Answer, -LeftOver, +Tag)
- % is called by read/4 after it has read a primary (the Term).
- % It checks for following postfix or infix operators.
-
-
- $read_exprtl0([atom(F)|S1], Term, Precedence, Answer, S, Tag) :-
- $read_ambigop(F, F1, F2, L1, O1, R1, L2, O2, Tag), !,
- ( $read_exprtl([infixop(F2,L1,O1,R1)|S1],0,Term,Precedence,Answer,S,
- Tag)
- ; $read_exprtl([postfixop(F1,L2,O2) |S1],0,Term,Precedence,Answer,S,
- Tag)
- ).
- $read_exprtl0([atom(F)|S1], Term, Precedence, Answer, S, Tag) :-
- $read_infixop(F, F0, L1, O1, R1, Tag), !,
- $read_exprtl([infixop(F0,L1,O1,R1)|S1],0,Term,Precedence,Answer,S,Tag).
- $read_exprtl0([atom(F)|S1], Term, Precedence, Answer, S, Tag) :-
- $read_postfixop(F, F0, L2, O2, Tag), !,
- $read_exprtl([postfixop(F0,L2,O2)|S1],0,Term,Precedence,Answer,S,Tag).
- $read_exprtl0([','|S1], Term, Precedence, Answer, S, Tag) :-
- Precedence >= 1000, !,
- $read(S1, 1000, Next, S2, Tag), !,
- $read_exprtl(S2, 1000, (Term,Next), Precedence, Answer, S, Tag).
- $read_exprtl0(['|'|S1], Term, Precedence, Answer, S, Tag) :-
- Precedence >= 1100, !,
- $read(S1, 1100, Next, S2, Tag), !,
- $read_exprtl(S2, 1100, (Term;Next), Precedence, Answer, S, Tag).
- $read_exprtl0([Thing|S1], _, _, _, _, _) :-
- $read_cfexpr(Thing, Culprit), !,
- $read_syntax_error([Culprit,follows,expression], [Thing|S1]).
- $read_exprtl0(S, Term, _, Term, S, _).
-
- :- mode($read_cfexpr,2,[nv,d]).
-
- $read_cfexpr(atom(_), atom).
- $read_cfexpr(var(_,_), variable).
- $read_cfexpr(number(_), number).
- $read_cfexpr(string(_), string).
- $read_cfexpr(' (', bracket).
- $read_cfexpr('(', bracket).
- $read_cfexpr('[', bracket).
- $read_cfexpr('{', bracket).
-
-
- :- mode($read_exprtl,7,[nv,d,d,c,d,d,d]).
-
- $read_exprtl([infixop(F,L,O,R)|S1], C, Term, Precedence, Answer, S, Tag) :-
- Precedence >= O, C =< L, !,
- $read(S1, R, Other, S2, Tag),
- $univ(Expr,[F,Term,Other]), /*!,*/
- $read_exprtl(S2, O, Expr, Precedence, Answer, S, Tag).
- $read_exprtl([postfixop(F,L,O)|S1], C, Term, Precedence, Answer, S, Tag) :-
- Precedence >= O, C =< L, !,
- $univ(Expr,[F,Term]),
- $read_peepop(S1, S2, Tag),
- $read_exprtl(S2, O, Expr, Precedence, Answer, S, Tag).
- $read_exprtl([','|S1], C, Term, Precedence, Answer, S, Tag) :-
- Precedence >= 1000, C < 1000, !,
- $read(S1, 1000, Next, S2, Tag), /*!,*/
- $read_exprtl(S2, 1000, (Term,Next), Precedence, Answer, S, Tag).
- $read_exprtl(['|'|S1], C, Term, Precedence, Answer, S, Tag) :-
- Precedence >= 1100, C < 1100, !,
- $read(S1, 1100, Next, S2, Tag), /*!,*/
- $read_exprtl(S2, 1100, (Term;Next), Precedence, Answer, S, Tag).
- $read_exprtl(S, _, Term, _, Term, S, _).
-
-
- % This business of syntax errors is tricky. When an error is detected,
- % we have to write out a message. We also have to note how far it was
- % to the end of the input, and for this we are obliged to use the data-
- % base. Then we fail all the way back to $read(), and that prints
- % the input list with a marker where the error was noticed. If subgoal_of
- % were available in compiled code we could use that to find the input
- % list without hacking the data base. The really hairy thing is that
- % the original code noted a possible error and backtracked on, so that
- % what looked at first sight like an error sometimes turned out to be
- % a wrong decision by the parser. This version of the parser makes
- % fewer wrong decisions, and $ goal was to get it to do no backtracking
- % at all. This goal has not yet been met, and it will still occasionally
- % report an error message and then decide that it is happy with the input
- % after all. Sorry about that.
-
- /* Modified by Saumya Debray, Nov 18 1986, to use SB-Prolog's database
- facilities to print out error messages. */
-
- $read_syntax_error(Message, List) :-
- $length(List,Length),
- $symtype('_$synerr'(_),X),
- ( (X =:= 0 ; not('_$synerr'(_))) -> /* _$synerr/1 undefined */
- $assert('_$synerr'(Length)) ;
- true
- ),
- !,
- fail.
-
- $read_syntax_error(List) :-
- $nl, $print('*** syntax error ***'), $nl,
- '_$synerr'(AfterError),
- $retract('_$synerr'(AfterError)),
- $length(List,Length),
- BeforeError is Length - AfterError,
- $read_display_list(List,BeforeError), !,
- fail.
-
- $read_display_list(X, 0) :-
- $print('<<here>> '), !,
- $read_display_list(X, 99999).
- $read_display_list([Head|Tail], BeforeError) :-
- $print_token(Head),
- $writename(' '),
- Left is BeforeError-1, !,
- $read_display_list(Tail, Left).
- $read_display_list([], _) :-
- $nl.
-
-
- $print_list([]) :- $nl.
- $print_list([Head|Tail]) :-
- $tab(1),
- $print_token(Head),
- $print_list(Tail).
-
- $print_token(atom(X)) :- !, $print(X).
- $print_token(var(V,X)) :- !, $print(X).
- $print_token(number(X)) :- !, $print(X).
- $print_token(string(X)) :- !, $print(X).
- $print_token(X) :- $print(X).
-
-
- /*
- % $read_tokens(TokenList, Dictionary)
- % returns a list of tokens. It is needed to "prime" read_tokens/2
- % with the initial blank, and to check for end of file. The
- % Dictionary is a list of AtomName=Variable pairs in no particular order.
- % The way end of file is handled is that everything else FAILS when it
- % hits character "-1", sometimes printing a warning. It might have been
- % an idea to return the atom 'end_of_file' instead of the same token list
- % that you'd have got from reading "end_of_file. ", but (1) this file is
- % for compatibility, and (b) there are good practical reasons for wanting
- % this behaviour. */
-
- $read_tokens(TokenList, Dictionary) :-
- $read_next_token(Type,Value),
- $read_insert_token(Type,Value,Dict,ListOfTokens),
- $append(Dict, [], Dict), !, /* fill in the "hole" at the end */
- Dictionary = Dict, /* unify explicitly so we read and */
- TokenList = ListOfTokens. /* then check even with filled in */
- /* arguments */
- $read_tokens([atom(end_of_file)], []). /* only thing that can go wrong */
-
- $read_next_token(Type, Value) :- '_$builtin'(135).
-
- $read_insert_token(X,Val,Dict,Tokens):-
- (X=:=0 ->
- /**0**/ /* punctuation */
- (Tokens = [Val | TokRest],
- $read_next_token(Type,Value),
- $read_insert_token(Type,Value,Dict,TokRest)
- );
- (X<3 ->
- (X=:=1 -> /* var */
- /**1**/
- (Val = Name, Tokens = [var(Var,Name) | TokRest],
- $read_lookup(Dict, Name=Var),
- $read_next_token(Type,Value),
- $read_insert_token(Type,Value,Dict,TokRest)
- );
- /**2**/ /* atom( */
- (Tokens = [atom(Val) | ['(' | TokRest]],
- $read_next_token(Type,Value),
- $read_insert_token(Type,Value,Dict,TokRest)
- )
- );
- (X<5 ->
- (X=:=3 ->
- /**3**/ /* number */
- (Tokens = [number(Val) | TokRest],
- $read_next_token(Type,Value),
- $read_insert_token(Type,Value,Dict,TokRest)
- ) ;
- /**4**/ /* atom */
- (Tokens = [atom(Val) | TokRest],
- $read_next_token(Type,Value),
- $read_insert_token(Type,Value,Dict,TokRest)
- )
- );
- (X<7 ->
- (X=:=5 ->
- /**5**/ /* end of clause */
- Tokens = [] ;
- /**6**/ /* uscore */
- (Tokens = [var(_,Val) | TokRest],
- $read_next_token(Type,Value),
- $read_insert_token(Type,Value,Dict,TokRest)
- )
- ) ;
- (X=:=7 ->
- /**7**/ /* semicolon */
- (Tokens = [atom((';')) | TokRest],
- $read_next_token(Type,Value),
- $read_insert_token(Type,Value,Dict,TokRest)
- );
- (X=:=8 ->
- /**8**/ /* end of file */
- fail ;
- /**9**/ /* string */
- (Tokens = [string(Val) | TokRest],
- $read_next_token(Type,Value),
- $read_insert_token(Type,Value,Dict,TokRest)
- )
- )
- )
- )
- )
- )
- ).
-
-
- % read_lookup is identical to memberchk except for argument order and
- % mode declaration.
-
- $read_lookup([X|_], X) :- !.
- $read_lookup([_|T], X) :- $read_lookup(T, X).
-
- /*
- The rest of this file is concerned with reading in entire module
- constructs into one term.
- eg. structure test/sig1 = struct
- fun fun1/0.
- test(fun1).
- end.
- is returned as the term
- structure('='('/'(test,sig1),[fun('/'(fun1,0)),test(fun1)]))
- which is the same as
- structure test/sig1 = [fun fun1/0,test(fun1)]
- */
-
- % $read_module/1
- %
- % Read in an entire module construct.
-
- $read_module(Answer) :-
- repeat,
- $read_tokens(Tokens, _),
- $process_tokens(Tokens, Term), !,
- Answer = Term.
-
- % $process_tokens/2
- %
- % Check for signature, structure or functor declarations, if none, then
- % process as if it is a standard term.
-
- $process_tokens([atom(signature)|Tail], Term) :- !,
- $get_signature(Tail, Term).
-
- $process_tokens([atom(structure)|Tail], Str) :- !,
- $get_structure_head(Tail, Head, Leftover),
- ( $get_strexpr(Leftover, Body, Sig, []) ->
- ( Sig == $dummy -> Str = (structure Head = Body) ;
- Str = (structure Head = Body/Sig) ) ;
- ( $writename('** Read Error : Bad structure declaration for '),
- $write(Head), $nl, fail ) ).
-
- $process_tokens([atom(functor)|Tail], Fun) :- !,
- $get_functor_head(Tail, Head, Leftover),
- ( $get_strexpr(Leftover, Body, Sig, []) ->
- ( Sig == $dummy -> Fun = (functor Head = Body) ;
- Fun = (functor Head = Body/Sig) ) ;
- ( $writename('** Read Error : Bad functor declaration for '),
- $write(Head), $nl, fail ) ).
-
- $process_tokens(Tokens, Term) :-
- $read(Tokens, 1200, Term, Leftover, perv),
- $read_all(Leftover).
-
- $process_tokens(Tokens, _) :-
- $read_syntax_error(Tokens).
-
- % $get_signature/2
- %
- % Read in the head of a signature declaration.
-
- $get_signature([atom(Atid), atom('='), atom(Atid2)],
- (signature Atid = Atid2) ) :- !.
- % ie. signature X = Y.
-
- $get_signature([atom(Atid), atom('='), atom(sig)|Spec],
- (signature Atid = Speclist) ) :- !,
- $get_speclist(Spec, Speclist, []).
- % ie. signature X = sig ... end.
-
- $get_signature([atom(Atid)|_], _) :- !,
- $writename('** Read Error : Bad signature declaration for '),
- $writename(Atid), $nl, fail.
-
- $get_signature(_, _) :- !,
- $writename('** Read Error : Bad signature declaration'), $nl, fail.
-
- % $get_speclist/3
- %
- % Read the signature body into a list.
-
- $get_speclist([atom(end_of_file)|_], _, _) :- !,
- $writename('** Read Error : Unexpected end-of-file in signature body'),
- $nl, fail.
-
- $get_speclist([atom(end)|Rest], [], Leftover) :- !,
- Rest = Leftover.
-
- $get_speclist([atom(structure)|Tail], [structure(Term)|List], Left) :- !,
- $get_structure_spec(Tail, Term) ->
- $get_speclist(List, Left) ;
- ( $writename('** Read Error : Bad structure spec in signature body'),
- $nl, fail ).
-
- $get_speclist(Tokens0, [Term|List], Left) :-
- $read_on_failure(Tokens0, Tokens),
- $read(Tokens, 1200, Term, Leftover, perv),
- % Note we use the standard read routines here. There cannot be
- % nested module constructs within a signature.
- $read_all(Leftover), !,
- $get_speclist(List, Left).
-
- $get_speclist(List, Left) :-
- $read_tokens(Tokens, _),
- $get_speclist(Tokens, List, Left).
-
- % $get_structure_spec/2
- %
- % Get the 'structure specstrb and ... and specstrb' part of the input.
-
- $get_structure_spec([atom(Str), atom('/'), atom(Sig)|Rest], Term) :-
- ( Sig = sig -> $get_speclist(Rest, Sig1, Rest1) ;
- ( Sig1 = Sig, Rest1 = Rest ) ),
- ( Rest1 = [] -> Term = Str/Sig1 ;
- ( Rest1 = [atom(and)|Tail],
- $get_structure_spec(Tail, Term2),
- Term = and(Str/Sig1, Term2) ) ).
-
- % $read_on_failure/2
- %
-
- $read_on_failure(Dec, Dec).
- $read_on_failure(_, Tokens) :-
- $read_tokens(Readin, _),
- $read_on_failure(Readin, Tokens).
-
- % $get_structure_head/3
- %
- % Accept the head of a structure declaration.
-
- $get_structure_head([atom(Atid), atom('/'), atom(sig)|Rest],
- Atid/Spec, Leftover) :- !,
- $get_speclist(Rest, Spec, [atom('=')|Leftover]).
- % ie. structure X/sig ... end = ... .
-
- $get_structure_head([atom(Atid), atom('/'), atom(Sig), atom('=')|Rest],
- Atid/Sig, Rest) :- !.
- % ie. structure X/Y = ... .
-
- $get_structure_head([atom(Atid), atom('=')|Rest], Atid, Rest) :- !.
- % ie. structure X = ... .
-
- $get_structure_head([atom(Atid)|_], _, _) :- !,
- $writename('** Read Error : Bad header in structure declaration for '),
- $writename(Atid), $nl, fail.
-
- $get_structure_head(_, _, _) :-
- $writename('** Read Error : Bad header in structure declaration'),
- $nl, fail.
-
- % $get_functor_head/3
- %
- % Accept the head of a functor declaration.
-
- $get_functor_head([atom(Atid), '('|Rest], Head, Left) :-
- $get_functor_args(Rest, Args, Leftover),
- ( Leftover = [atom('/'), atom(sig)|Tail] ->
- $get_speclist(Tail, Spec, [atom('=')|Left]) ;
- ( Leftover = [atom('/'), atom(Spec), atom('=')|Left] ->
- true ;
- ( Spec = $dummy,
- Leftover = [atom('=')|Left]) ) ),
- $univ(Head0, [Atid|Args]),
- ( Spec = $dummy -> Head = Head0 ;
- Head = Head0/Spec ), !.
-
- $get_functor_head([atom(Atid)|_], _, _) :- !,
- $writename('** Read Error : Bad header in functor declaration for '),
- $writename(Atid), $nl, fail.
-
- $get_functor_head(_, _, _) :- !,
- $writename('** Read Error : Bad header in functor declaration'),
- $nl, fail.
-
- % $get_functor_args/3
- %
- % Read in the arguments to a functor. Note that these can themselves be
- % structures.
-
- $get_functor_args([atom(Atid), atom('/'), atom(Sig)|Rest],
- [Result|Args], Left) :-
- ( Sig == sig -> $get_speclist(Rest, Spec, Leftover) ;
- ( Sig = Spec,
- Leftover = Rest ) ),
- ( Leftover = [')'|Left] ->
- ( Args = [],
- Result = Atid/Spec ) ;
- ( Leftover = [atom('sharing')|More] ->
- $get_functor_sharing(More, Atid, Spec, Left, Result) ;
- ( Leftover = [','|More],
- Result = Atid/Spec, !,
- $get_functor_args(More, Args, Left) ) ) ), !.
-
- $get_functor_args(_, _, _) :-
- $writename('** Read Error : Bad functor arguments'), $nl, fail.
-
- % $get_functor_sharing/4
- %
- % Read in the sharing portion of a functors argument list.
-
- $get_functor_sharing(More, Atid, Spec, Leftover, sharing(Atid/Spec,Result)) :-
- $append(Read, [')'|Leftover], More),
- $read(Read, 1200, Result, [], perv).
-
- $get_functor_sharing(_, _, _, _, _) :-
- $writename('** Read Error : Bad sharing constraint in functor arguments'),
- $nl, fail.
-
- % $get_strexpr/4
- %
- % Read in a strexpr (the body of a structure).
-
- $get_strexpr([atom(struct)|Rest], Body, Sig, Leftover) :- !,
- $get_structure_body(Rest, Body, Sig, Leftover).
-
- $get_strexpr([atom(Atid),'('|Rest], Body, Sig, Leftover0) :- !,
- $get_strexpr_args(Rest, Args, Leftover),
- $univ(Body, [Atid|Args]),
- ( Leftover = [] ->
- ( Sig = $dummy,
- Leftover0 = [] ) ;
- ( Leftover = [atom('/'), atom(sig)|Tokens] ->
- $get_speclist(Tokens, Sig, Leftover0) ;
- Leftover = [atom('/'), atom(Sig)|Leftover0]) ).
-
- $get_strexpr(Tokens, Body, Sig, Leftover) :-
- $get_strexpr_id(Tokens, Body, Left),
- ( Left = [atom('/'),atom(sig)|Rest] ->
- $get_speclist(Rest, Sig, Leftover) ;
- ( Left = [atom('/'),atom(Sig)|Leftover] ->
- true ;
- ( Leftover = Left,
- Sig = $dummy ) ) ).
-
- % $get_strexpr_id/3
- %
-
- $get_strexpr_id([atom(Id),atom(':'),atom(Id1),atom(':')|Rest],
- Id:Path, Leftover) :- !,
- $get_strexpr_id([atom(Id1),atom(':')|Rest], Path, Leftover).
- $get_strexpr_id([atom(Id),atom(':'),atom(Id1)|Rest], Id:Id1, Rest) :- !.
- $get_strexpr_id([atom(Id)|Rest], Id, Rest).
-
- % $get_structure_body/4
- %
- % Read a structure body (within struct .. end delimiters) into a list.
-
- $get_structure_body([atom(end), atom('/'), atom(sig)|Rest], [], Sig,
- Leftover) :- !,
- $get_speclist(Rest, Sig, Leftover).
- % Check for trailing signature.
-
- $get_structure_body([atom(end), atom('/'), atom(Atid)|Leftover], [], Atid,
- Leftover) :- !.
- % Check for trailing signature.
-
- $get_structure_body([atom(end)|Leftover], [], $dummy, Leftover) :- !.
-
- $get_structure_body([atom(end_of_file)|_], _, _, _) :- !,
- $writename('** Read Error : Unexpected end-of-file in structure body'),
- $nl, fail.
-
- $get_structure_body(Tokens0, [Term|List], Sig, Leftover) :-
- $read_on_failure(Tokens0, Tokens),
- $process_tokens(Tokens, Term), !,
- % Recursive call here as structure can contain nested structures.
- $get_structure_body(List, Sig, Leftover).
-
- $get_structure_body(List, Sig, Leftover) :-
- $read_tokens(Tokens, _),
- $get_structure_body(Tokens, List, Sig, Leftover).
-
- % $get_structure_args/3
- %
- % Read arguments to a functor application.
-
- $get_strexpr_args(Tokens, [Arg0|Args], Left) :-
- $get_strexpr(Tokens, Arg, Sig, Leftover),
- ( Sig = $dummy -> Arg0 = Arg ;
- Arg0 = Arg/Sig ),
- ( Leftover = [')'|Left] ->
- Args = [] ;
- ( Leftover = [','|More], !,
- $get_strexpr_args(More, Args, Left) ) ), !.
-
- $get_strexpr_args(_, _, _, _) :-
- $writename('** Read Error : Bad arguments in functor application expression'),
- $nl, fail.
-